package com.ecnu.sei.app.teacher;

import java.util.HashSet;
import java.util.Set;

import com.ecnu.sei.app.course.CourseInfo;
import com.ecnu.sei.app.course.ExamInfo;
import com.ecnu.sei.app.course.ICourse;
import com.ecnu.sei.app.resources.Time;

public abstract class AbstractTeacher implements ITeacher {
  
  protected String name;
  protected int limit;
  protected int count; // number of proctors
  protected Set<Time> timeTable = new HashSet<Time>(); // proctoring time
  protected Set<ICourse> courses = new HashSet<ICourse>(); // proctoring courses
  protected Set<Time> leaves = null;    // take leave
   
  public AbstractTeacher() {}
  
  public AbstractTeacher(String name) {
    this(name, 4, new HashSet<Time>());
  }
  
  public AbstractTeacher(String name, Set<Time> leaves) {
    this(name, 4, leaves);  
  }
  
  public AbstractTeacher(String name, int limit, Set<Time> leaves) {
    this.name = name;
    this.limit = limit;
    this.count = 0;
    this.leaves = leaves != null ? leaves : new HashSet<Time>();
  }
 
  @Override
  public String getName() {
    return name;
  }
  
  @Override
  public int getCount() {
    return count;
  }
  
  @Override
  public void addProctor(ICourse course) {
    courses.add(course);
    ExamInfo examInfo = course.getCourseInfo().getExamInfo();
    timeTable.add(examInfo.getTime());
  }
  
  @Override
  public void addLeave(Time time) {
    leaves.add(time);
  }
  
  public AbstractTeacher setName(String name) {
    this.name = name;
    return this;
  }
  
  public AbstractTeacher setLeaves(Set<Time> leaves) {
    this.leaves = leaves;
    return this;
  }
  
 /*  common rules:
  * 
  *  1. not exceed limit
  *  2. not take leave
  *  3. not proctor at both DayHour.MORN_TWO and DayHour.AFTN_ONE
  */
  
  @Override
  public boolean isAvailableFor(ICourse course) {
    ExamInfo examInfo = course.getCourseInfo().getExamInfo();
    Time time = examInfo.getTime();
    
    if (count >= limit) {
      return false;
    }
   
    if (isTakeLeave(time)) {
      return false;
    }
    
    
    if (!timeTable.contains(time)) {
      for (Time t : timeTable) {
        if (t.isContHalfDay(time)) {
          return false;
        }
      }
      return true;
    }
  
    return false;
  }
 
  private boolean isTakeLeave(Time time) {
    return leaves.contains(time);
  }
  
}
